#include "InitSyntaxAnalyzer.h"
#include "First.h"
#include "AST.h"
#include "Follow.h"
#include "PredictTable.h"
#include "visit.h"

unordered_map<string, unordered_set<string>> FirstSet;   // 存放FIRST集合
unordered_map<string, unordered_set<string>> FirstSetBeta;  // 存放β的first
unordered_map<string, unordered_set<string>> FollowSet;
unordered_map<string, vector<string>> production_map; // 存放产生式
unordered_set<string> VnSet;
unordered_set<string> VtSet;
map<int, string> map_i2s; // 符号单词Map，符号码为键，单词为值
map<string, int> map_s2i; // 单词符号Map，单词为键，符号码为值
Production* productionsArray[GRAMMARSIZE]; // 产生式数组
vector<pair<string, ASTNode*>> stackVector; // 当前栈
// id, value
vector<pair<int,string>> readerVector; // 待读队列
string start;
map<string, int> predictionTable;
ASTNode* root = nullptr; // 语法树根节点

//class Syner {
//
//};


int syntax_analysis(string path) {
    
    int stackTop = 1;
    int readerTop = 0;
    int index = 1;
    stackVector.push_back(make_pair(to_string(map_s2i["#"]), new ASTNode("#")));
    stackVector.push_back(make_pair(start, new ASTNode(start)));
    ostringstream outputBuffer;
    string filepath = path;
    string out;

    try {
        readToReader(filepath);
    } catch (const exception& e) {
        cerr << "Failed to Read LA Result：" << e.what() << endl;
        return 1;
    }
    readerVector.push_back(make_pair(map_s2i["#"], ""));

    while (stackTop >=0) {
        outputBuffer << index << "\t";
        string str = stackVector[stackTop].first;
        string s;
        int temp;
        try {
            temp = atoi(stackVector[stackTop].first.c_str());
        } catch (const std::invalid_argument& e) {
            cout << "Invalid argument: " << e.what() << endl;
            return 1;
        }


        if (temp != 0) {
            str = map_i2s.at(temp);
        }
        

        cout << index << " ";
        cout << str;
        outputBuffer << str;

        

        cout << "#" << map_i2s[readerVector[0].first] << " ";
        outputBuffer << "#" << map_i2s[readerVector[0].first] << " ";


       

        if (str==map_i2s.at(readerVector[readerTop].first)
            || temp == readerVector[readerTop].first) {

            stackVector.erase(stackVector.begin() + stackTop);
            readerVector.erase(readerVector.begin() + readerTop);
            stackTop--;
            cout << "move" << endl;
            outputBuffer << "\t" << "move" << "\n";
        } else {
             
            int i = getProductionIndex(readerTop, stackTop);
            if (i == -1) {
                cout << "Error" << endl;
                outputBuffer << "Error";
                return 1;
            } else {
                stackTop = stackPush(stackTop, *productionsArray[i], root);
                // cout << "Hello World!" << endl;
                cout << "reduction" << std::endl;
                outputBuffer << "\t" << "reduction" << "\n";
                
            }
        }
        ++index;
    }

    if (stackTop == -1) {
        cout << "Accept" << endl;
        outputBuffer<<"Accept"<<endl;
    }

    string outputPath=path;
    std::string toSearch = "lexical_analysis";
    std::string toReplace = "syntax_analysis";
    size_t pos = outputPath.find(toSearch);

    // 如果找到了匹配的字符串，则进行替换
    if (pos != std::string::npos) {
        outputPath.replace(pos, toSearch.length(), toReplace);
    }



    ofstream outputFile(outputPath);
    if (!outputFile) {
        cerr << "Failed to Open Output File" << outputPath << endl;
        return 1;
    }

    outputFile << outputBuffer.str();
    outputFile.close();
    return 0;
}

void init() {
    start="Program";
    initMap();
    initProductions();
    First(); // 计算First集合
    for (const string& c : VnSet) {
        vector<string> l = production_map[c];
        for (const string& s : l){
            getFirstOfBeta(s);
        }
    }
    Follow(); // 计算Follow集合
    output(); // 打印结果
    setPrediction();//构建预测分析表
}

void printAST(ASTNode* node, int depth = 0) {
    if (!node) return;
    for (int i = 0; i < depth; i++) cout << "  ";
    cout << node->type;
    if (!node->value.empty()) cout << " (" << node->value << ")";
    cout << endl;
    for (auto child : node->children) {
        printAST(child, depth + 1);
    }
}

void AST_NodeTraversal_ValueAssignment(ASTNode* node) {
    if (!node) return;
    
    // 递归处理子节点
    for (auto child : node->children) {
        AST_NodeTraversal_ValueAssignment(child);
    }
    
    // 设置当前节点value
    if (node->type == "constDef" || node->type == "varDef" || 
        node->type == "funcDef" || node->type == "funcFParam") {
        for (auto child : node->children) {
            if (child->type == "Ident") {
                node->value = child->value;
                break;
            }
        }
    } else if (node->type == "bType") {
        node->value = "int";
    } else if (node->type == "funcType") {
        node->value = "void";
    } else if (node->type == "argVarDef"){
        string init_val, equal_symbol;
        for(auto child : node->children){
            if(child->type == "="){
                equal_symbol = child->value;
            } else if(child->type == "initVal"){
                init_val = child->value;
            }
        }
        node->value = equal_symbol + init_val;
    } else if (node->type == "initVal"){
        // initVal -> exp
        // 这里假设 exp 是唯一的子节点
        node->value = node->children[0]->value;
    } else if (node->type == "lVal") {
        for (auto child : node->children) {
            if (child->type == "Ident") {
                node->value = child->value;
                break;
            }
        }
    } else if (node->type == "number") {
        for (auto child : node->children) {
            if (child->type == "INT") {
                node->value = child->value;
                break;
            }
        }
    } else if (node->type == "primaryExp") {
        if (!node->children.empty()) {
            ASTNode* firstChild = node->children[0];
            if (firstChild->type == "number") {
                node->value = firstChild->value;
            } else if (firstChild->type == "exp") {
                node->value = firstChild->value;
            }
        }
    } else if(node->type == "exp"){
        // exp -> assignExp
        // 这里假设 assignExp 是唯一的子节点
        node -> value = node -> children[0] -> value;
    } else if (node->type == "stmt" && !node->children.empty()) {
        if (node->children[0]->type == "return") {
            ASTNode* argExp = nullptr;
            for (auto child : node->children) {
                if (child->type == "argExp") {
                    argExp = child;
                    break;
                }
            }
            if (argExp && !argExp->children.empty()) {
                node->value = argExp->children[0]->value;
            }
        }
    } else if (node->type == "unaryOp") {
            // 从子节点获取操作符符号（如 "+"）
            if (!node->children.empty()) {
                node->value = node->children[0]->value;
            }
    } else if (node->type == "unaryExp") {
        // 处理三种情况：一元运算符、函数调用、基本表达式
        if (node->children.size() == 2 && node->children[0]->type == "unaryOp") {
            // 一元运算符表达式（如 -5）
            string op = node->children[0]->value;
            string operand = node->children[1]->value;
            node->value = op + operand; // 例如 "-5"
        } else if (node->children.size() >= 1 && node->children[0]->type == "Ident") {
            // 函数调用（如 foo(1,2)）
            string funcName = node->children[0]->value;
            string args = "";
            if (node->children.size() > 1 && node->children[1]->type == "callFunc") {
                ASTNode* callFunc = node->children[1];
                if (!callFunc->children.empty() && callFunc->children[0]->type == "funcRParams") {
                    args = callFunc->children[0]->value;
                }
            }
            node->value = funcName + "(" + args + ")"; // 例如 "foo(1,2)"
        } else if (node->children.size() == 1 && node->children[0]->type == "primaryExp") {
            // 基本表达式（如 (3+4) 或 42）
            node->value = node->children[0]->value;
        }
    } else if (node->type == "funcFParams") {
        // 参数列表（如 "1,2"）
        // process_funcFParams(node);
    } else if (node->type == "mulExp") {
        // 处理乘法、除法、取模运算
        if (node->children.size() == 2) {
            string left = node->children[0]->value;
            string right = node->children[1]->value;
            if (!right.empty()) {
                // 例如 "3*4"
                node->value = left + right; // 实际应为计算数值，此处简化为字符串拼接
            } else {
                node->value = left;
            }
        }
    } else if (node->type == "addExp") {
        // 处理加法、减法运算
        if (node->children.size() == 2) {
            string left = node->children[0]->value;
            string right = node->children[1]->value;
            if (!right.empty()) {
                // 例如 "5+2"
                node->value = left + right; // 实际应为计算数值，此处简化为字符串拼接
            } else {
                node->value = left;
            }
        }
    }else if (node->type == "addExpAtom") {
        if (node->children.size() >= 2) {
            string op = node->children[0]->value;
            string right = node->children[1]->value;
            node->value = op + right;
        }
    } else if (node->type == "relExp") {
        if (node->children.size() == 2) {
            string left = node->children[0]->value;
            string right = node->children[1]->value;
            node->value = left + right;
        }
    } else if (node->type == "relExpAtom") {
        if (node->children.size() >= 2) {
            string op = node->children[0]->value;
            string operand = node->children[1]->value;
            node->value = op + operand;
        }
    } else if (node->type == "eqExp") {
        if (node->children.size() == 2) {
            string left = node->children[0]->value;
            string right = node->children[1]->value;
            node->value = left + right;
        }
    } else if (node->type == "eqExpAtom") {
        if (node->children.size() >= 2) {
            string op = node->children[0]->value;
            string operand = node->children[1]->value;
            node->value = op + operand;
        }
    } else if (node->type == "assignExp") {
        if (node->children.size() == 2) {
            string left = node->children[0]->value;
            string right = node->children[1]->value;
            
            if(right == ""){
                node -> value = left;
            }
            else{
                if(right[0] == '='){
                    node->value = left + right;
                } else {
                    node->value = left + "=" + right;
                }
            }
        }
    } else if (node->type == "assignExpAtom") {
        if (node->children.size() >= 2) {
            string right = node->children[1]->value;
            node->value = "=" + right;
        }
    } else if (node->type == "constExp") {
        if (!node->children.empty()) {
            node->value = node->children[0]->value;
        }
    } else if (node->type == "constInitVal"){
        if (!node->children.empty()) {
            node->value = node->children[0]->value;
        }
    }
}


int main() {

    init();
    
    for(int i = 6; i <= 6; i++) {

        string file_path = "/home/seary/compiler/C--Compiler/results/lexical_analysis_result_of_0" + to_string(i) + "_var_defn.sy";

        syntax_analysis(file_path);
        cout << "=======================================" << endl;

        AST_NodeTraversal_ValueAssignment(root);
        printAST(root);

        visit_Program(root);

        cout << "=======================================" << endl;

    }

    return 0;
}
